package cn.micai.base.lambda;

import cn.micai.base.math.I;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 描述：Java 8 – Filter a Map examples
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/6/21 19:47
 */
public class FilterAMapExample {

    public static void main(String [] args) {

        Map<Integer, String> hostings = new HashMap<>();

        hostings.put(1, "linode.com");
        hostings.put(2, "heroku.com");
        hostings.put(3, "digitalocean.com");
        hostings.put(4, "aws.amazon.com");

        // 1.Java 8 – Filter a Map

        // Befor Java 8
        String result = "";
        for (Map.Entry<Integer, String> entry : hostings.entrySet()) {
            if ("aws.amazon.com".equals(entry.getValue())) {
                result = entry.getValue();
            }
        }
        System.out.println("Before Java 8 : " + result);

        // Map -> Stream -> Filter ->String
        String result2 = hostings.entrySet().stream()
                .filter(map -> "aws.amazon.com".equals(map.getValue()))
                .map(map -> map.getValue())
                .collect(Collectors.joining());
        System.out.println("With Java 8 : " + result2);

        // filter more values
        String result3 = hostings.entrySet().stream()
                .filter(x -> {
                    if (!x.getValue().contains("amazon") && !x.getValue().contains("digitalocean")) {
                        return true;
                    }
                    return false;
                })
                .map(map -> map.getValue())
                .collect(Collectors.joining(","));
        System.out.println("With Java 8 : " + result3);


        // 2. Java 8 – Filter a Map #2

        // Map -> Stream -> Filter ->Map
        Map<Integer, String> result4 = hostings.entrySet().stream()
                .filter(map -> map.getKey() == 2)
                .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
        System.out.println(result4); //output:{2=heroku.com}

        Map<Integer, String> result5 = hostings.entrySet().stream()
                .filter(map -> map.getKey() <= 3)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        System.out.println(result5); //output : {1=linode.com, 2=heroku.com, 3=digitalocean.com}

        // 3.Java 8 - Filter a Map #3 - Predicate

        // {1=linode.com}
        Map<Integer, String> filteredMap = filterByValue(hostings, x -> x.contains("linode.com"));
        System.out.println(filteredMap);

        // {1=linode.com, 4=aws.amazon.com, 5=aws2.amazon.com}
        Map<Integer, String> filteredMap2 = filterByValue(hostings, x -> x.contains("aws") || x.contains("linode"));
        System.out.println(filteredMap2);

        // {4=aws.amazon.com}
        Map<Integer, String> filteredMap3 = filterByValue(hostings, x -> (x.contains("aws") && !x.contains("aws2")));
        System.out.println(filteredMap3);

        // {1=linode.com, 2=heroku.com}
        Map<Integer, String> filteredMap4 = filterByValue(hostings, x -> x.length() <= 10);
        System.out.println(filteredMap4);

    }

    // Generic Map filterbyvalue, with predicate
    public static <K, V> Map<K, V> filterByValue(Map<K, V> map, Predicate<V> predicate) {
        return map.entrySet().stream()
                .filter(x->predicate.test(x.getValue()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }
}
